<?php

namespace App\Http\Controllers\Api;

use App\ActivityBargainInitiate;
use App\ActivityGroup;
use App\ActivityGroupAdd;
use App\ActivityGroupRefund;
use App\BooksInfo;
use App\Exceptions\OrderException;
use App\Exceptions\PaymentException;
use App\Express;
use App\Goods;
use App\GoodSpu;
use App\Http\Services\UserManager;
use App\OrderItem;
use App\Orders;
use App\RechargePackage;
use App\User;
use App\UserAddress;
use App\UserBooks;
use App\UserCoupon;
use App\UserInfo;
use App\UserIntegralRecord;
use App\UserSpendRecord;
use Illuminate\Http\Request;
use EasyWeChat\Factory;
use App\Http\Requests;
use App\Http\Controllers\Controller;

class PaymentController extends Controller
{
    /**
     * 微信支付接口
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws OrderException
     * @throws PaymentException
     */
    public function weChatPayment(Request $request){
        /** @var User $user */
        $user = UserManager::isLogin($request);
        if(!$user)
            return response()->json(['level' => 'error','message' => '请先登录!','data' => 'no_login']);

        $orderNum = $request->get('order_num');

        /** @var Orders $thisOrder */
        $thisOrder = Orders::whereOrderNum($orderNum)->first();
        if(!$thisOrder || ($thisOrder && $thisOrder->status == 6))
            return response()->json(['level' => 'error','message' => '订单不存在或已取消']);

        if($thisOrder->is_pay == 1)
            return response()->json(['level' => 'error','message' => '订单已支付']);

        if($thisOrder->status == 1 && (strtotime($thisOrder->created_at) + (30 * 60)) < time()){
            $thisOrder->status = 6;
            $thisOrder->save();

            /** @var UserCoupon $thisCoupon */
            $thisCoupon = UserCoupon::whereId($thisOrder->coupon_id)->first();
            if($thisCoupon){
                $thisCoupon->is_locking = 0;
                $thisCoupon->save();
            }

            return response()->json(['level' => 'error','message' => '订单已失效']);
        }

        if($thisOrder->type == 'bargain'){
            /** @var ActivityBargainInitiate $thisActivityBargainInitiate */
            $thisActivityBargainInitiate = ActivityBargainInitiate::whereId($thisOrder->activity_id)->first();
            if(!$thisActivityBargainInitiate)
                return response()->json(['level' => 'error','message' => '未找到该活动']);

            if(strtotime($thisActivityBargainInitiate->end_time) <= time())
                return response()->json(['level' => 'error','message' => '活动已过期，请参与其他活动']);

        }

        if($thisOrder->type == 'group'){
            /** @var ActivityGroup $thisActivityGroup */
            $thisActivityGroup = ActivityGroup::whereId($thisOrder->activity_id)->whereStatus(1)->first();
            if(!$thisActivityGroup)
                return response()->json(['level' => 'error','message' => '活动已下架']);

            if(strtotime($thisActivityGroup->end_time) <= time())
                return response()->json(['level' => 'error','message' => '活动已过期，请参与其他活动']);

            if($thisOrder->group_type == 3){
                /** @var ActivityGroupAdd $activityGroupAdd */
                $activityGroupAdd = ActivityGroupAdd::whereId($thisOrder->group_id)->first();
                if(!$activityGroupAdd)
                    return response()->json(['level' => 'error','message' => '该拼团不存在']);

                if($thisActivityGroup->max_group_num <= $activityGroupAdd->group_num)
                    return response()->json(['level' => 'error','message' => '抱歉，拼团人数已满']);

                if (strtotime($activityGroupAdd->end_time) <= time())
                    return response()->json(['level' => 'error','message' => '该拼团已过期']);

                if($activityGroupAdd->status != 0)
                    return response()->json(['level' => 'error','message' => '拼团已结束']);
            }
        }

        /** @var OrderItem $orderItem */
        $orderItems = OrderItem::whereOrderId($thisOrder->id)->get();
        if(count($orderItems) > 0){
            foreach($orderItems as $orderItem){
                /** @var Goods $thisGoods */
                $thisGoods = Goods::whereId($orderItem->good_id)->whereIsShop(1)->first();
                if(!$thisGoods)
                    return response()->json(['level' => 'error','message' => '订单商品已下架']);


                if($thisOrder->coupon_id !=0){
                    if($thisOrder->type=="integral")
                        return response()->json(['level' => 'error','message' => '积分商品不能使用优惠券']);


                    $userCoupon=UserCoupon::whereId($thisOrder->coupon_id)->whereIsUse(0)->first();
                    if(!$userCoupon)
                        return response()->json(['level' => 'error','message' => '找不到优惠券']);

                }

                if($thisGoods->type=="common" || $thisGoods->type=="bargain" || $thisGoods->type == 'group'){
                    /** @var GoodSpu $thisGoodsSpu */
                    $thisGoodsSpu = GoodSpu::whereId($orderItem->good_spu_id)->whereGoodsId($orderItem->good_id)->whereStatus(1)->first();
                    if(!$thisGoodsSpu)
                        return response()->json(['level' => 'error','message' => '订单属性不存在']);

                    //库存判断
                    if($thisGoodsSpu->stock < $orderItem->num)
                        return response()->json(['level' => 'error','message' => '商品库存不足']);
                }


                /** @积分兑换类型 */
                if($thisGoods->type=="integral"){

                    if($thisGoods->stock < $orderItem->num)
                        return response()->json(['level' => 'error','message' => '商品库存不足']);

                    /** @var UserInfo $userInfo */
                    $userInfo=UserInfo::whereUserId($thisOrder->user_id)->first();
                    if(!$userInfo)
                        return response()->json(['level' => 'error','message' => '找不到用户信息']);

                    if($userInfo->integral < $orderItem->integral)
                        return response()->json(['level' => 'error','message' => '积分不足']);

                }

            }
        }

        $config = [
            // 必要配置
            'app_id'             => env('WXAPP_KEY'),
            'mch_id'             => env('WECHAT_PAYMENT_MERCHANT_ID'),
            'key'                => env('WECHAT_PAYMENT_KEY'),   // API 密钥
        ];

        $app = Factory::payment($config);

        $result = $app->order->unify([
            'body' => '读物购买',
            'out_trade_no' => $thisOrder->order_num,
            'total_fee' => (float)$thisOrder->s_amount * 100,
            'spbill_create_ip' => '', // 可选，如不传该参数，SDK 将会自动获取相应 IP 地址
            'notify_url' => route('Api.Payment.WeChatPayCallback'), // 支付结果通知网址，如果不设置则会使用配置里的默认地址
            'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
            'openid' => $user->wx_openid,
        ]);

        if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){
            $jssdk = $app->jssdk;
            $prepayId = $result['prepay_id'];
            $json = $jssdk->bridgeConfig($prepayId); // 返回 json 字符串，如果想返回数组，传第二个参数 false

            return response()->json(['level' => 'success','message' => '订单创建成功','data'=>json_decode($json)]);
        }else{
            return response()->json(['level' => 'error','message' => '订单创建失败','data' => $result]);
        }
    }

    public function WeChatPayCallback(Request $request){
        $config = [
            // 必要配置
            'app_id'             => env('WXAPP_KEY'),
            'mch_id'             => env('WECHAT_PAYMENT_MERCHANT_ID'),
            'key'                => env('WECHAT_PAYMENT_KEY'),   // API 密钥
        ];

        $app = Factory::payment($config);

        $response = $app->handlePaidNotify(function ($message, $fail) {
            $ordersNum = $message['out_trade_no'];

            /** @var Orders $order */
            $order = Orders::whereOrderNum($ordersNum)->first();

            if(!$order || ($order && $order->is_pay == 1)){
                return true;
            }

            if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态，不代表支付状态
                // 用户是否支付成功
                if (array_get($message, 'result_code') === 'SUCCESS') {
                    $order->pay_time = date('Y-m-d H:i:s',time()); // 更新支付时间为当前时间
                    $order->pay_type = 'wechat';
                    $order->is_pay   = 1;
                    $order->status   = 2;


                    if($order->type == 'group'){
                        /** @var ActivityGroup $activityGroup */
                        $activityGroup = ActivityGroup::whereId($order->activity_id)->first();
                        if(!$activityGroup)
                            return response()->json(['level' => 'error','message' => '该活动不存在']);

                        if($order->group_type == 2){
                            $newActivityGroupAdd = new ActivityGroupAdd();
                            $newActivityGroupAdd->user_id     = $order->user_id;
                            $newActivityGroupAdd->order_num   = $order->order_num;
                            $newActivityGroupAdd->ag_id       = $order->activity_id;
                            $newActivityGroupAdd->start_time  = date('Y-m-d H:i:s',time());
                            $newActivityGroupAdd->end_time    = date('Y-m-d H:i:s',time() + $activityGroup->group_effective_time * 3600);
                            $newActivityGroupAdd->group_num   = 1;
                            $newActivityGroupAdd->save();
                        }

                        if($order->group_type == 3){
                            /** @var ActivityGroupAdd $activityGroupAdd */
                            $activityGroupAdd = ActivityGroupAdd::whereId($order->group_id)->first();
                            if(!$activityGroupAdd)
                                return response()->json(['level' => 'error','message' => '该拼团不存在']);

                            if($activityGroup->max_group_num > $activityGroupAdd->group_num){
                                $newActivityGroupAdd = new ActivityGroupAdd();
                                $newActivityGroupAdd->user_id   = $order->user_id;
                                $newActivityGroupAdd->order_num = $order->order_num;
                                $newActivityGroupAdd->ag_id     = $order->activity_id;
                                $newActivityGroupAdd->group_id  = $order->group_id;
                                $newActivityGroupAdd->save();

                                $activityGroupAdd->group_num = $activityGroupAdd->group_num + 1;
                                $activityGroupAdd->save();

                                if($activityGroup->max_group_num <= $activityGroupAdd->group_num){
                                    $activityGroupAdd->status = 1;
                                    $activityGroupAdd->save();

                                    /** @var ActivityGroupAdd $activityGroupAdd */
                                    $allActivityGroupAdd = ActivityGroupAdd::whereGroupId($activityGroupAdd->id)->whereStatus(0)->get();
                                    if(count($allActivityGroupAdd) > 0){
                                        foreach($allActivityGroupAdd as $activityGroupAdd){
                                            $activityGroupAdd->status = 1;
                                            $activityGroupAdd->save();
                                        }
                                    }
                                }
                            }
                        }
                    }

                    /** @var OrderItem $orderItem */
                    $orderItems = OrderItem::whereOrderId($order->id)->get();
                    if(count($orderItems) > 0){
                        foreach($orderItems as $orderItem){
                            /** @var Goods $thisGoods */
                            $thisGoods = Goods::whereId($orderItem->good_id)->whereIsShop(1)->first();
                            if(!$thisGoods)
                                return response()->json(['level' => 'error','message' => '订单商品已下架']);

                            if($order->coupon_id!=0){
                                if($thisGoods->type=="integral")
                                    return response()->json(['level' => 'error','message' => '积分商品不能使用优惠券']);

                                $userCoupon=UserCoupon::whereId($order->coupon_id)->whereIsUse(0)->first();
                                if(!$userCoupon)
                                    return response()->json(['level' => 'error','message' => '找不到优惠券']);

                                $userCoupon->is_use=1;
                                $userCoupon->save();

                            }

                            if($thisGoods->type=="common"){
                                /** @var GoodSpu $thisGoodsSpu */
                                $thisGoodsSpu = GoodSpu::whereId($orderItem->good_spu_id)->whereGoodsId($orderItem->good_id)->whereStatus(1)->first();
                                if(!$thisGoodsSpu)
                                    return response()->json(['level' => 'error','message' => '订单属性不存在']);

                                //库存处理
                                if($thisGoodsSpu->stock < $orderItem->num)
                                    return response()->json(['level' => 'error','message' => '商品库存不足']);

                                $goodsNum = (int)$thisGoodsSpu->stock - (int)$orderItem->num;
                                $thisGoodsSpu->stock      = $goodsNum;
                                $thisGoodsSpu->save();

                                $thisGoods->sale_count    = $thisGoods->sale_count + $orderItem->num;
                                $thisGoods->save();
                            }

                            /** @积分兑换类型 */
                            if($thisGoods->type=="integral"){

                                if($thisGoods->stock < $orderItem->num)
                                    return response()->json(['level' => 'error','message' => '商品库存不足']);

                                $goodsStock = (int)$thisGoods->stock -(int)$orderItem->num;

                                //todo 商品库存记录
                                $thisGoods->sale_count    = $thisGoods->sale_count + $orderItem->num;
                                $thisGoods->stock=$goodsStock;
                                $thisGoods->save();

                                //todo 积分记录
                                $userInfo=UserInfo::whereUserId($order->user_id)->first();
                                if(!$userInfo)
                                    return response()->json(['level' => 'error','message' => '找不到用户信息']);


                                $userInfo->integral=(int)$userInfo->integral - (int)$orderItem->integral;
                                $userInfo->save();

                                $newUserIntegralRecord = new UserIntegralRecord();
                                $newUserIntegralRecord->integral = -($orderItem->integral);
                                $newUserIntegralRecord->num     =$orderItem->num;
                                $newUserIntegralRecord->order_num = $order->order_num;
                                $newUserIntegralRecord->user_id = $order->user_id;
                                $newUserIntegralRecord->type = $thisGoods->type;
                                $newUserIntegralRecord->goods_name = $thisGoods->name;
                                $newUserIntegralRecord->save();
                            }

                            if($thisGoods->type=="bargain"){
                                /** @var GoodSpu $thisGoodsSpu */
                                $thisGoodsSpu = GoodSpu::whereId($orderItem->good_spu_id)->whereGoodsId($orderItem->good_id)->whereStatus(1)->first();
                                if(!$thisGoodsSpu)
                                    return response()->json(['level' => 'error','message' => '订单属性不存在']);

                                //库存处理
                                if($thisGoodsSpu->stock < $orderItem->num)
                                    return response()->json(['level' => 'error','message' => '商品库存不足']);

                                $goodsNum = (int)$thisGoodsSpu->stock - (int)$orderItem->num;
                                $thisGoodsSpu->stock      = $goodsNum;
                                $thisGoodsSpu->save();

                                $thisGoods->sale_count    = $thisGoods->sale_count + $orderItem->num;
                                $thisGoods->save();

                                /** @var ActivityBargainInitiate $thisActivityBargainInitiate */
                                $thisActivityBargainInitiate = ActivityBargainInitiate::whereId($order->activity_id)->first();
                                if(!$thisActivityBargainInitiate)
                                    return response()->json(['level' => 'error','message' => '未找到该活动']);

                                $thisActivityBargainInitiate->status = 1;
                                $thisActivityBargainInitiate->save();

                            }

                            if($thisGoods->type=="group"){
                                /** @var GoodSpu $thisGoodsSpu */
                                $thisGoodsSpu = GoodSpu::whereId($orderItem->good_spu_id)->whereGoodsId($orderItem->good_id)->whereStatus(1)->first();
                                if (!$thisGoodsSpu)
                                    return response()->json(['level' => 'error', 'message' => '订单属性不存在']);

                                //库存处理
                                if ($thisGoodsSpu->stock < $orderItem->num)
                                    return response()->json(['level' => 'error', 'message' => '商品库存不足']);

                                $goodsNum = (int)$thisGoodsSpu->stock - (int)$orderItem->num;
                                $thisGoodsSpu->stock = $goodsNum;
                                $thisGoodsSpu->save();

                                if($order->group_type == 2){
                                    $ActivityGroupAdd = ActivityGroupAdd::whereAgId($order->activity_id)->whereOrderNum($order->order_num)->whereUserId($order->user_id)->whereStatus(1)->first();
                                    if($ActivityGroupAdd){
                                        $thisGoods->sale_count = $thisGoods->sale_count + $orderItem->num;
                                        $thisGoods->save();
                                    }else{
                                        $order->status = 8;
                                    }
                                }

                                if($order->group_type == 3) {
                                    /** @var ActivityGroupAdd $ActivityGroupAdd */
                                    $ActivityGroupAdd = ActivityGroupAdd::whereGroupId($order->group_id)->whereOrderNum($order->order_num)->whereUserId($order->user_id)->whereStatus(1)->first();
                                    if($ActivityGroupAdd){
                                        $thisGoods->sale_count = $thisGoods->sale_count + $orderItem->num;
                                        $thisGoods->save();

                                        /** @var ActivityGroupAdd $groupAdd */
                                        $groupAdd = ActivityGroupAdd::whereId($ActivityGroupAdd->group_id)->whereStatus(1)->first();
                                        if($groupAdd){
                                            /** @var Orders $groupOrder */
                                            $groupOrder = Orders::whereOrderNum($groupAdd->order_num)->whereStatus(8)->first();
                                            if($groupOrder){
                                                $groupOrder->status = 2;
                                                $groupOrder->save();
                                            }
                                        }
                                    }else{
                                        $order->status = 8;
                                    }
                                }
                            }

                        }
                    }

                    // 用户支付失败
                } elseif (array_get($message, 'result_code') === 'FAIL') {
                    $order->status = 0;
                }
            } else {
                return $fail('通信失败，请稍后再通知我');
            }

            $order->save(); // 保存订单

            return true; // 返回处理完成

        });

        return $response;
    }

    /**
     * 退款接口（订单不可为空）
     * @param Orders $thisOrder
     * @param $reason
     * @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
     */
    public static function Refund(Orders $thisOrder,$reason){
        $config = [
            // 必要配置
            'app_id'             => env('WXAPP_KEY'),
            'mch_id'             => env('WECHAT_PAYMENT_MERCHANT_ID'),
            'key'                => env('WECHAT_PAYMENT_KEY'),   // API 密钥

            'cert_path'          => '',
            'key_path'           => '',

        ];

        $app = Factory::payment($config);

        $result = $app->refund->byOutTradeNumber($thisOrder->order_num, $thisOrder->order_num, $thisOrder->s_amount, $thisOrder->s_amount, [
            // 可在此处传入其他参数，详细参数见微信支付文档
            'refund_desc' => $reason,
        ]);

        return $result;
    }

    /**
     * 退款查询接口（订单不可为空）
     * @param Orders $thisOrder
     * @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
     */
    public static function selectRefund(Orders $thisOrder){
        $config = [
            // 必要配置
            'app_id'             => env('WXAPP_KEY'),
            'mch_id'             => env('WECHAT_PAYMENT_MERCHANT_ID'),
            'key'                => env('WECHAT_PAYMENT_KEY'),   // API 密钥

            'cert_path'          => '',
            'key_path'           => '',

        ];

        $app = Factory::payment($config);

        $result = $app->refund->queryByTransactionId($thisOrder->order_num);

        return $result;
    }
}
